/******************************************************************************
 *  _____     _____
 *  \  __\    \  __\
 *   \ \_\\    \ \_\\
 *    \  __\SS  \  __\roject
 *     \_\       \_\
 *
 * Mateusz Maciąg, Rafał Urbański
 * Komputerowe Systemy Sterowania
 *****************************************************************************/

#include "OscilloscopeData.h"

#include <limits>

namespace RafMat
{
namespace UI
{

OscilloscopeData::OscilloscopeData(int bufferCapacity)
    : m_series(boost::circular_buffer<QPointF>(bufferCapacity)),
      mc_bufCapacity(bufferCapacity),
      m_shrinkCounter(100),
      m_shrinkTime(100)
{
    this->clear();
}

OscilloscopeData::OscilloscopeData(int bufferCapacity,
                                   const std::vector<QPointF>& points)
    : m_series(boost::circular_buffer<QPointF>(bufferCapacity)),
      mc_bufCapacity(bufferCapacity),
      m_shrinkCounter(100),
      m_shrinkTime(100)
{
    this->clear();
    std::vector<QPointF>::const_iterator it;
    for(it = points.begin(); it != points.end(); ++it)
    {
       this->insertSample(*it);
    }
}

void OscilloscopeData::setShrinkTime(int shrinkTime)
{
    if(m_shrinkCounter > shrinkTime)
        m_shrinkCounter = shrinkTime;

    m_shrinkTime = m_shrinkCounter;
}

void OscilloscopeData::actualizeBoundingRect(QPointF newSample)
{
    if(--m_shrinkCounter)
    {
        m_boundingRect |= QRectF(newSample.x(), newSample.y(), 1e-300, 1e-300);
        m_boundingRect.setLeft(m_series[0].x());
    }
    else
    {
        actualizeBoundingRectAllSamples();
        m_shrinkCounter = m_shrinkTime;
    }
}

void OscilloscopeData::actualizeBoundingRectAllSamples()
{
    boost::circular_buffer<QPointF>::iterator it;

    double xMin = std::numeric_limits<double>::max(),
           xMax = mc_bufCapacity,
           yMin = std::numeric_limits<double>::max(),
           yMax = std::numeric_limits<double>::min();

    for(it = m_series.begin(); it != m_series.end(); ++it)
    {
        double x = it->x();
        double y = it->y();
        if(x < xMin) xMin = x;
        if(x > xMax) xMax = x;
        if(y < yMin) yMin = y;
        if(y > yMax) yMax = y;
    }
    m_boundingRect.setLeft(xMin);
    m_boundingRect.setRight(xMax);
    m_boundingRect.setTop(yMax);
    m_boundingRect.setBottom(yMin);
}

}   // UI namespace
}   // RafMat namespace
